library(dplyr)
library(readr)
library(ggplot2)
library(htmlwidgets)
library(plotly)
library(gganimate)
library(ggforce)
library(patchwork)
library(gifski)
# data sources
library(gapminder)
library(palmerpenguins)Interactive plots are great to give more control to the audience to explore your figure. Probably the most widely used solution in the R and Python community is the plotly package. The R plotly package provides an excellent way to create interactive charts. Let’s recreate the lineplot from yesterday and see if interactivity helps. As a first step we create the plot and store it in an object.
stocks_df <- read_csv("data/stocks.csv")
#>
#> -- Column specification --------------------------------------------------------
#> cols(
#> date = col_date(format = ""),
#> company = col_character(),
#> stock_closing = col_double(),
#> stock_base = col_double(),
#> stock_index = col_double()
#> )
p_stock <- ggplot(stocks_df, aes(date, stock_index, color = company)) +
geom_line() +
theme_minimal()Then we just simply use the ggplotly() function from the plotly package.
ggplotly(p_stock)As additional step, we can create a highlight key with the similarly named function to make sure that we get the “highlight on hoover” behaviour that is useful in these sort of plots. Then use this so called SharedData object to create the ggplot base which then we wrap into the ggplotly. The tooltip option regulates what sort of info we want to see when hovering over the selected data.
stocks_hl <- highlight_key(stocks_df, ~company)
p_hl <- ggplot(stocks_hl, aes(date, stock_index, color = company)) +
geom_line() +
theme_minimal()
stocks_plotly_hl <- ggplotly(p_hl, tooltip = "all")Finally, the created plotly object should go into the highlight() function. We can customize the action that triggers the highlight (click, hover or selected) and how to disable the highlight effect.
hl_final <- highlight(stocks_plotly_hl, on = "plotly_hover", off = "plotly_deselect")
hl_finalTo save the interactive plot locally, we need to create a standalone html document for the plot and save it with the saveWidget function from the htmlwidgets package.
saveWidget(as_widget(hl_final), "stock_chart.html")We can create animated charts with the gganimate() package. As an example we are recreating the famous animated bubble chart from Hans Rosling. This example is adapted from the package’s documentation. We are using the country_colors palette from the gapminder package and also adding a minimum and maximum range for the size aesthetic with the scale_size() function.
ggplot(gapminder, aes(x = gdpPercap, y = lifeExp, size = pop, color = country)) +
geom_point(alpha = 0.8) +
scale_size(range = c(2, 12), guide = FALSE) +
scale_color_manual(values = country_colors, guide = FALSE) +
scale_x_log10() +
facet_wrap(~continent)When the static plot is ready we animate it with the transition_time() from the gganimate package. There are a number of transition functions in the package in addition to this one.
gapminder_anim <- ggplot(gapminder, aes(x = gdpPercap, y = lifeExp, size = pop, color = country)) +
geom_point(alpha = 0.8) +
scale_size(range = c(2, 12), guide = FALSE) +
scale_color_manual(values = country_colors, guide = FALSE) +
scale_x_log10() +
facet_wrap(~continent) +
labs(title = 'Year: {frame_time}', x = 'GDP per capita', y = 'life expectancy') +
transition_time(year) +
ease_aes('linear')
gapminder_animTo export your animated plot, use the anim_save. Sometimes you get an error, so we need to specify the renderer as well with the animate package.
animate(gapminder_anim, duration = 5, fps = 20, width = 200, height = 200, renderer = gifski_renderer())
anim_save("gapminder_animation.gif")Creating a custom theme function is probably the most accessible way to extend ggplot. The easiest way to start out is to use an existing theme and start from there. We’ll going to be using the theme_minimal as a baseline and add a couple of things that we also modified in the previous session. We’ll name it theme_dotted. The new theme is essentially a new function that wraps the original theme and modifies certain elemets with the use of the %+replace% operator.
theme_dotted <- function() {
theme_minimal() %+replace%
theme(
panel.grid.major.y = element_line(color = "grey", size = 0.1, linetype = "dotted"),
panel.background = element_blank(),
axis.line = element_line(colour = "grey"),
legend.title = element_text(size = 12),
text = element_text(face = "plain", family = "sans"),
legend.key=element_blank()
)
}Now let’s use it with our penguins data.
penguins_df <- penguins
ggplot(penguins_df, aes(x = body_mass_g, y = flipper_length_mm, color = species)) +
geom_point() +
theme_dotted()
#> Warning: Removed 2 rows containing missing values (geom_point).The easiest way to arrange multiple plost is to use the pathwork package. The syntax is really straighforward as it uses a simple notation with +, or / and | to arrange our plots. Let’s create three plots, two sina charts, and one scatterplot.
p_scatter <- ggplot(penguins_df, aes(x = body_mass_g, y = flipper_length_mm, color = species)) +
geom_point() +
theme_dotted()
p_sina1 <- ggplot(penguins_df, aes(x = species, y = body_mass_g)) +
geom_sina(aes(color = species), alpha = 0.2) +
geom_violin(alpha = 0.25, fill = "grey") +
theme_dotted() +
theme(legend.position = "none")
p_sina2 <- ggplot(penguins_df, aes(x = species, y = flipper_length_mm)) +
geom_sina(aes(color = species), alpha = 0.2) +
geom_violin(alpha = 0.25, fill = "grey") +
theme_dotted() +
theme(legend.position = "none")After we are done with our plots, lets arrange the scatterplot on the top and the two sina plots on the bottom next to each other.
p_scatter / (p_sina1 | p_sina2)
#> Warning: Removed 2 rows containing missing values (geom_point).
#> Warning: Removed 2 rows containing non-finite values (stat_sina).
#> Warning: Removed 2 rows containing non-finite values (stat_ydensity).
#> Warning: Removed 2 rows containing non-finite values (stat_sina).
#> Warning: Removed 2 rows containing non-finite values (stat_ydensity).The patchwork package is very flexible, and the documentation is great so if you need to create these type of figures where you need to add together multiple plots check out its webpage: https://patchwork.data-imaginist.com/index.html